package com.david.dubbo.excutors;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author David
 * @version V1.0
 * @Package com.david.dubbo.excutors
 * @date 2021/4/15 15:48
 */
public class WatchingThreadPool  extends FixedThreadPool  implements  Runnable{
    // 定义线程池使用的阀值
    private  static  final  double  ALARM_PERCENT = 0.90;
    private  final Map<URL, ThreadPoolExecutor>    THREAD_POOLS = new ConcurrentHashMap<>();
    public  WatchingThreadPool(){
        // 每隔3秒打印线程使用情况
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this,1,3, TimeUnit.SECONDS);
    }
    // 通过父类创建线程池
    @Override
    public Executor getExecutor(URL url) {
        final  Executor executor = super.getExecutor(url);
        if(executor instanceof  ThreadPoolExecutor){
            THREAD_POOLS.put(url,(ThreadPoolExecutor)executor);
        }
        return  executor;
    }
    @Override
    public void run() {
        System.out.println("线程池检测开始......"+THREAD_POOLS.size());
        // 遍历线程池
        for (Map.Entry<URL,ThreadPoolExecutor> entry: THREAD_POOLS.entrySet()){
            final   URL  url = entry.getKey();
            final   ThreadPoolExecutor  executor = entry.getValue();
            // 计算相关指标
            final  int  activeCount  = executor.getActiveCount();
            final  int  poolSize = executor.getCorePoolSize();
            double  usedPercent = activeCount / (poolSize*1.0);
            System.out.println("存活线程数："+activeCount);
            System.out.println("最大线程数："+poolSize);
            System.out.println(" 线程使用比 " +usedPercent );
            System.out.println("线程使用率："+(usedPercent*100)+"%");
            if (usedPercent > ALARM_PERCENT){
                System.out.printf("超出警戒线"+":"+url.getIp()+":"+usedPercent*100+":"+url);
            }
        }
        System.out.println("线程池检测结束......");
    }
}
